package fra;

public class MatrixFra extends Matrix2<Fra> {
	/*构造函数**********************************************/
	public MatrixFra(){
		super("NoName");
	}
	public MatrixFra(String name) {
		super(name);
	}
	public MatrixFra(String name,Size size) {
		super(name,size);
	}
	public MatrixFra(Size size) {
		super(size);
	}
	public MatrixFra(String name,int row,int col) {
		super(name,row,col);
	}
	public MatrixFra(int row,int col) {
		super(row,col);
	}
	public MatrixFra(String name,int len) {
		super(name,len);
	}
	public MatrixFra(int len) {
		super(len);
	}
	public MatrixFra(String name,Fra[][] objArr,Size size){
		super(name,objArr,size);
	}	
	public MatrixFra(Fra[][] objArr,Size size){
		super(objArr,size);
	}
	public MatrixFra(String name,Fra[][] objArr,int row,int col){
		super(name,objArr,row,col);
	}
	public MatrixFra(Fra[][] objArr,int row,int col){
		super(objArr,row,col);
	}
	public MatrixFra(String name,Fra[][] objArr,int len){
		super(name,objArr,len);
	}
	public MatrixFra(Fra[][] objArr,int len){
		super(objArr,len);
	}
	public MatrixFra(String name,Fra[] objArr,boolean isDefault){
		super(name,objArr,isDefault);		
	}
	public MatrixFra(Fra[] objArr,boolean isDefault){
		super(objArr,isDefault);
	}
	public MatrixFra(String name,Fra[] objArr){
		super(name,objArr);
	}
	public MatrixFra(Fra[] objArr){
		super(objArr);
	}
	public MatrixFra(MatrixFra m){
		super(m);
	}
	public MatrixFra(String name,int[][] objArr,Size size){
		super(name,size);
		for (int i = 0; i <size.row; i++) {
			for (int j = 0; j < size.col; j++) {
				this.objArr[i][j]=new Fra(objArr[i][j]);
			}
		}
	}
	public MatrixFra(int[][] objArr,Size size){
		this("NoName",objArr,size);
	}
	public MatrixFra(int[][] objArr,int row,int col){
		this(objArr,new Size(row,col));
	}
	public MatrixFra(int[][] objArr,int len){
		this(objArr,new Size(len));
	}
	public MatrixFra(String name,long[][] objArr,Size size){
		super(name,size);
		for (int i = 0; i <size.row; i++) {
			for (int j = 0; j < size.col; j++) {
				this.objArr[i][j]=new Fra(objArr[i][j]);
			}
		}		
	}
	public MatrixFra(long[][] objArr,Size size){
		this("NoName",objArr,size);
	}
	public MatrixFra(long[][] objArr,int row,int col){
		this(objArr,new Size(row,col));
	}
	public MatrixFra(long[][] objArr,int len){
		this(objArr,new Size(len));
	}
	public MatrixFra(String name,double[][] objArr,Size size){
		super(name,size);
		for (int i = 0; i <size.row; i++) {
			for (int j = 0; j < size.col; j++) {
				this.objArr[i][j]=new Fra(objArr[i][j]);
			}
		}		
	}
	public MatrixFra(double[][] objArr,Size size){
		this("NoName",objArr,size);
	}
	public MatrixFra(double[][] objArr,int row,int col){
		this(objArr,new Size(row,col));
	}
	public MatrixFra(double[][] objArr,int len){
		this(objArr,new Size(len));
	}
	public MatrixFra(String name,int[] objArr,boolean isDefault){
		super(name,isDefault?new Size(1,objArr.length):new Size(objArr.length,1));
		if(isDefault){
			for (int i = 0; i < objArr.length; i++) {
				this.objArr[0][i]=new Fra(objArr[i]);
			}
		}else{
			for (int i = 0; i < objArr.length; i++) {
				this.objArr[i][0]=new Fra(objArr[i]);
			}
		}		
	}
	public MatrixFra(String name,int[] objArr){
		this(name,objArr,true);
	}
	public MatrixFra(int[] objArr){
		this("NoName",objArr);
	}
	public MatrixFra(String name,long[] objArr,boolean isDefault){
		super(name,isDefault?new Size(1,objArr.length):new Size(objArr.length,1));
		if(isDefault){
			for (int i = 0; i < objArr.length; i++) {
				this.objArr[0][i]=new Fra(objArr[i]);
			}
		}else{
			for (int i = 0; i < objArr.length; i++) {
				this.objArr[i][0]=new Fra(objArr[i]);
			}
		}		
	}
	public MatrixFra(String name,long[] objArr){
		this(name,objArr,true);
	}
	public MatrixFra(long[] objArr){
		this("NoName",objArr);
	}
	public MatrixFra(String name,double[] objArr,boolean isDefault){
		super(name,isDefault?new Size(1,objArr.length):new Size(objArr.length,1));
		if(isDefault){
			for (int i = 0; i < objArr.length; i++) {
				this.objArr[0][i]=new Fra(objArr[i]);
			}
		}else{
			for (int i = 0; i < objArr.length; i++) {
				this.objArr[i][0]=new Fra(objArr[i]);
			}
		}		
	}
	public MatrixFra(String name,double[] objArr){
		this(name,objArr,true);
	}
	public MatrixFra(double[] objArr){
		this("NoName",objArr);
	}
	public MatrixFra(Vector v){
		this(v.get());
	}
	/*静态方法***************************************************/
	/**
	 * 自然步长增长
	 * @param start
	 * @param step
	 * @param size
	 * @return
	 */
	public static MatrixFra round(double start,double step,Size size){
		MatrixFra mf=new MatrixFra("MatrixFra_round",size);
		int len=mf.getCol()*mf.getRow();
		for (int i = 0; i < len; i++) {
			mf.set(i+1,new Fra(start));
			start+=step;
		}
		return mf;
	}
	public static MatrixFra round(double start,Size size){
		return round(start,1,size);
	}
	public static MatrixFra round(Size size){
		return round(1,1,size);
	}
	public static MatrixFra round(double start,double step,int size){
		MatrixFra mf=new MatrixFra("MatrixFra_round",new Size(size));
		int len=mf.getCol()*mf.getRow();
		for (int i = 0; i < len; i++) {
			mf.set(i+1,new Fra(start));
			start+=step;
		}
		return mf;
	}
	public static MatrixFra round(double start,int size){
		return round(start,1,new Size(size));
	}
	public static MatrixFra round(int size){
		return round(1,1,new Size(size));
	}
	/**
	 * 全1矩阵
	 * @param size
	 * @return
	 */
	public static MatrixFra ones(Size size){
		MatrixFra mf=round(1,0,size);
		mf.setName("MatrixFra_ones");
		return mf;
	}
	public static MatrixFra ones(int size){
		MatrixFra mf=round(1,0,new Size(size));
		mf.setName("MatrixFra_ones");
		return mf;
	}
	/**
	 * 零矩阵
	 * @param size
	 * @return
	 */
	public static MatrixFra zeros(Size size){
		MatrixFra mf=round(0,0,size);
		mf.setName("MatrixFra_zeros");
		return mf;
	}
	public static MatrixFra zeros(int size){
		MatrixFra mf=round(0,0,new Size(size));
		mf.setName("MatrixFra_zeros");
		return mf;
	}
	/**
	 * 元矩阵
	 * @param len
	 * @return
	 */
	public static MatrixFra diag(int len){
		MatrixFra mf=new MatrixFra(new Size(len));
		for (int i = 0; i < mf.getRow(); i++) {
			for (int j = 0; j < mf.getCol(); j++) {
				if(i==j){
					mf.set(i, j, 1);
				}else{
					mf.set(i, j, 0);
				}
			}
		}
		return mf;
	}
	/**
	 * 随机数矩阵
	 * @param size
	 * @return
	 */
	public static MatrixFra random(Size size){
		MatrixFra mf=new MatrixFra("MatrixFra_random",size);
		int len=mf.getCol()*mf.getRow();
		for (int i = 0; i < len; i++) {
			mf.set(i+1, Math.random());
		}
		return mf;
	}
	public static MatrixFra random(int len){
		return random(new Size(len));
	}
	/**
	 * 随机数矩阵 整数
	 * @param maxValue
	 * @param size
	 * @return
	 */
	public static MatrixFra randomInt(int maxValue,Size size){
		MatrixFra mf=new MatrixFra("MatrixFra_random",size);
		int len=mf.getCol()*mf.getRow();
		for (int i = 0; i < len; i++) {
			mf.set(i+1,Math.floor((Math.random()*1E+10)%maxValue));
		}
		return mf;
	}
	public static MatrixFra randomInt(int maxValue,int len){
		return randomInt(maxValue,new Size(len));
	}
	/**
	 * 随机数矩阵 boolean
	 * @param size
	 * @return
	 */
	public static MatrixFra randomBolean(Size size){
		return randomInt(2, size);
	}
	public static MatrixFra randomBolean(int len){
		return randomBolean(new Size(len));
	}
	
	public static MatrixFra toMatrixFra(Matrix2<Fra> ma){
		MatrixFra mf=new MatrixFra(ma.getName(),ma.size);
		int len=mf.getCol()*mf.getRow();
		for (int i = 0; i < len; i++) {
			mf.set(i+1, ma.get(i+1));
		}
		return mf;
	}
	/*功能***************************************************/
	/**
	 * 加法
	 * @param f2
	 * @return
	 */
	public MatrixFra plus(MatrixFra f2){
		if(!size.equals(f2.size)){
			throw new RuntimeException("两矩阵行列不一致");
		}
		for (int i = 0; i < getRow(); i++) {
			for (int j = 0; j < getCol(); j++) {
				set(i,j,get(i, j).plus(f2.get(i, j)));
			}
		}
		return this;
	}
	/**
	 * 减法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra minis(MatrixFra f2){
		if(!size.equals(f2.size)){
			throw new RuntimeException("两矩阵行列不一致");
		}
		for (int i = 0; i < getRow(); i++) {
			for (int j = 0; j < getCol(); j++) {
				set(i,j,get(i, j).minis(f2.get(i, j)));
			}
		}
		return this;
	}
	/**
	 * 乘法运算
	 * @return
	 */
	public MatrixFra multiplication(MatrixFra f2){
		if(!size.equals(f2.size)){
			throw new RuntimeException("两矩阵行列不一致");
		}
		for (int i = 0; i < getRow(); i++) {
			for (int j = 0; j < getCol(); j++) {
				set(i,j,get(i, j).multiplication(f2.get(i, j)));
			}
		}
		return this;
	}
	/**
	 * 除法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra division(MatrixFra f2){
		if(!size.equals(f2.size)){
			throw new RuntimeException("两矩阵行列不一致");
		}
		for (int i = 0; i < getRow(); i++) {
			for (int j = 0; j < getCol(); j++) {
				set(i,j,get(i, j).division(f2.get(i, j)));
			}
		}
		return this;		
	}
	
	/**
	 * 加法
	 * @param f2
	 * @return
	 */
	public MatrixFra plus(Fra f2){
		int len=getRow()*getCol();
		for (int i = 0; i < len; i++) {
			set(i+1, get(i+1).plus(f2));
		}
		return this;		
	}
	/**
	 * 减法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra minis(Fra f2){
		int len=getRow()*getCol();
		for (int i = 0; i < len; i++) {
			set(i+1, get(i+1).minis(f2));
		}
		return this;		
	}
	/**
	 * 乘法运算
	 * @return
	 */
	public MatrixFra multiplication(Fra f2){
		int len=getRow()*getCol();
		for (int i = 0; i < len; i++) {
			set(i+1, get(i+1).multiplication(f2));
		}
		return this;
	}
	/**
	 * 除法 左
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra division(Fra f2){
		int len=getRow()*getCol();
		for (int i = 0; i < len; i++) {
			set(i+1, get(i+1).division(f2));
		}
		return this;	
	}
	/**
	 * 计算矩阵列或行的平均值
	 * @param isDefault
	 * @return
	 */
	public MatrixFra mean(boolean isDefault){
		MatrixFra mf;
		if(isDefault){
			mf=MatrixFra.zeros(new Size(1,getCol()));
			if(getRow()>0){
				for (int i = 0; i <getCol(); i++) {
					Fra f=new Fra(0);
					for (int j = 0; j < getRow(); j++) {
						f.plus(get(j,i));
					}
					f.division(new Fra(getRow()));
					mf.set(i+1, f);
				}
			}
		}else{
			mf=MatrixFra.zeros(new Size(getRow(),1));
			if(getCol()>0){
				for (int i = 0; i <getRow(); i++) {
					Fra f=new Fra(0);
					for (int j = 0; j < getCol(); j++) {
						f.plus(get(i, j));
					}
					mf.set(i+1, f);
					f.division(new Fra(getCol()));
				}				
			}
		}
		return mf;
	}
	/**
	 * 计算矩阵列的平均值
	 * @param isDefault
	 * @return
	 */
	public MatrixFra mean(){
		return mean(true);
	}
	/**
	 * 调整
	 * @param size
	 * @return
	 */
	public MatrixFra reshape(Size size){
		int len=size.col*size.row;
		int l=getRow()*getCol();
		MatrixFra mf=MatrixFra.zeros(size);
		for (int i = 0; i < len && i < l; i++) {
			mf.set(i+1, get(i+1));
		}		
		return mf;
	}
	public String toString(int a) {
		StringBuilder sb=new StringBuilder();
		sb.append(this.name);
		if(isEmpty()){
			sb.append(" = [\t]\n");
		}else{
			sb.append(" = \n[\t");
			for (int i = 0; i < getRow(); i++) {
				if(i>0)
					sb.append("\n\t");
				for (int j = 0; j < getCol(); j++) {
					Fra f=get(i, j);
					if(f==null||f.getInteger()==null){
						f=new Fra();
					}
					sb.append(f.toString(a));
					sb.append("\t");
				}
			}		
			sb.append("]\n");
		}
		return sb.toString();
	}
	public String toNumberString(int a){
		StringBuilder sb=new StringBuilder();
		sb.append(this.name);
		if(isEmpty()){
			sb.append(" = [\t]\n");
		}else{
			sb.append(" = \n[\t");
			for (int i = 0; i < getRow(); i++) {
				if(i>0)
					sb.append("\n\t");
				for (int j = 0; j < getCol(); j++) {
					Fra f=get(i, j);
					if(f==null||f.getInteger()==null){
						f=new Fra();
					}
					sb.append(M.toString(f.get(a).toString()));
					sb.append("\t");
				}
			}		
			sb.append("]\n");
		}
		return sb.toString();
	}
	public String toCsvString(int a){
		StringBuilder sb=new StringBuilder("");
		if(!isEmpty()){
			for (int i = 0; i < getRow(); i++) {
				if(i>0)
					sb.append("\n");
				for (int j = 0; j < getCol(); j++) {
					Fra f=get(i, j);
					if(f==null||f.getInteger()==null){
						f=new Fra();
					}
					sb.append(M.toString(f.get(a).toString()));
					if(j<getCol()-1)
						sb.append(",");
				}
			}		
		}
		return sb.toString();
	}
	/*get方法*********************************************************/
	public Fra get(int i,int j){
		if(i>=size.row||j>=size.col){
			throw new ArrayIndexOutOfBoundsException("数组越界");
		}
		if(objArr[i][j]==null)return null;
		Fra fra=(Fra)objArr[i][j];
		return fra.clone();
	}
	public Fra get(int index){
		if(index<1||index>getRow()*getCol()){
			throw new ArrayIndexOutOfBoundsException("数组越界");
		}
		index-=1;
		if(objArr[index%getRow()][index/getRow()]==null)return null;
		 Fra fra=(Fra)objArr[index%getRow()][index/getRow()];
		return fra.clone();
	}
	public Fra getValue(int i,int j){
		if(i>=size.row||j>=size.col){
			throw new ArrayIndexOutOfBoundsException("数组越界");
		}
		if(objArr[i][j]==null)return null;
		Fra fra=(Fra)objArr[i][j];
		return fra;		
	}
	public Fra getValue(int index){
		if(index<1||index>getRow()*getCol()){
			throw new ArrayIndexOutOfBoundsException("数组越界");
		}
		index-=1;
		if(objArr[index%getRow()][index/getRow()]==null)return null;
		 Fra fra=(Fra)objArr[index%getRow()][index/getRow()];
		return fra;
	}
	/*set方法*********************************************************/
	public void set(int obj){
		set(new Fra(obj));
	}
	public void set(int i,int j,int obj){
		set(i,j,new Fra(obj));
	}
	public void set(int index,int obj){
		set(index,new Fra(obj));
	}
	public void set(long obj){
		set(new Fra(obj));
	}
	public void set(int i,int j,long obj){
		set(i,j,new Fra(obj));
	}
	public void set(int index,long obj){
		set(index,new Fra(obj));
	}
	public void set(double obj){
		set(new Fra(obj));
	}
	public void set(int i,int j,double obj){
		set(i,j,new Fra(obj));
	}
	public void set(int index,double obj){
		set(index,new Fra(obj));
	}
	
	public static void main(String[] args) {
		MatrixFra f=MatrixFra.randomInt(10,3);
		System.out.println(f);
		System.out.println(f.turn());
	}
}
